package com.leedarson;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.leedarson.utils.FrontEndConfig;
import com.leedarson.utils.LeedarsonGenerator;
import com.leedarson.utils.LeedarsonTemplateEngine;

@RestController
@RequestMapping
public class CoreController {

	// 项目名
	String projectname = "mlgb";

	// 项目的contextpath,这个会作用于前端打包后访问的地址。
	String contextpath = "mlgb.hr";

	// 项目生成的路径
	String projectGeneratePath = "D:\\1\\mlgb";

	// 请填写好你的大名
	String author = "type u name";

	// 数据库连接四件套，不用多说了吧。
//	String dburl = "jdbc:mysql://192.168.8.125:3306/test?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8";
	String dburl = "jdbc:mysql://192.168.8.143:30360/appDB?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai";


	String driverName = "com.mysql.cj.jdbc.Driver";
	String dbusername = "root";
	String dbpassword = "123";

	private static final LeedarsonTemplateEngine TEMPLATE_ENGINE = new LeedarsonTemplateEngine();
	static LeedarsonGenerator mpg = new LeedarsonGenerator();

	@RequestMapping("/table")
	JSONArray gettablelist() {
		initEngine();
		List<TableInfo> tableList = mpg.getTableList();
		JSONArray parseArray = JSONArray.parseArray(JSON.toJSONString(tableList));
		return parseArray;
	}

	/**
	 * 修改后的生成方法，直接就吧前端JS返回的格式转化为对应的MAP和LIST，这样同一个格式从前端到后台tpl文件输出都是统一的。<br>
	 *
	 * @auhor 86136
	 * @Create_Date: 2020年10月8日上午11:22:17
	 * @last_modify by 86136 at 2020年10月8日上午11:22:17 <br>
	 * @Why_and_What_is_modified:
	 * @param result
	 * @return
	 */
	@RequestMapping("/generate")
	String generate2(@RequestBody() HashMap<String, HashMap<String, Object>> result) {
		//result
		//{role={noFE={}, pclist={querycolumn=[id, roleName, roleDescribe], listcolumn=[id, roleName, roleDescribe]}},
		// user={pclist={querycolumn=[id, name, age, email, roleId], listcolumn=[id, name, age, email, roleId]}}}
		//
		Set<String> tableSet = result.keySet();
		String[] tableArray = tableSet.toArray(String[]::new);
		//
		Map<String, Object> preSetMap = new HashMap<String, Object>();
		preSetMap.put("projectname", "olivier2");// 项目名
		preSetMap.put("contextPath", "olivier2.hr");// 非要把namespace加入到contextpath里去，呵呵
		mpg.getCfg().setMap(preSetMap);
		//
		FrontEndConfig.setFrontEndConfig(result);
		//
		mpg.getStrategy().setInclude(tableArray);
//		mpg.frontsideConfig = result;
		mpg.execute();
		return "ok";
	}

	@Deprecated
	@RequestMapping("/generate2")
	String generate(@RequestBody() JSONObject result) {
		// result的格式范例
		// {
		// "list": [{
		// "querycolumn": ["id", "name", "age"],
		// "listcolumn": ["age", "email", "roleId"],
		// "table": "user"
		// }],
		// "table": {
		// "user": ["backendsupport", "listsupport"]
		// }
		// }
		JSONObject tableConfig = result.getJSONObject("table");// 获得需要生成的表，以及每个表需要生成的模块。
		String[] tableArray = tableConfig.keySet().toArray(String[]::new);
		//
		//
		// 这里面是初始化的时候就设定好的内容，因此只能增加不能减少。
		// 对list的支持
		Map<String, Object> preSetMap = new HashMap<String, Object>();
		preSetMap.put("projectname", projectname);
		preSetMap.put("contextPath", contextpath);// 非要把namespace加入到contextpath里去，呵呵
		//
//		HashMap<String, HashMap> tableFrontendMap = new HashMap<String, HashMap>();
//		//
//		JSONArray listArray = result.getJSONArray("list");
//		listArray.forEach(a -> {
//			JSONObject joa = (JSONObject) a;
//			String tablename = joa.getString("table");
//			HashMap<String, HashMap> frontMap = new HashMap<>();
//			if (tableFrontendMap.containsKey(tablename)) {
//				frontMap = tableFrontendMap.get(tablename);
//			}
//			HashMap<String, Object[]> listmap = new HashMap<>();
//			listmap.put("querycolumn", joa.getJSONArray("querycolumn").toArray());
//			listmap.put("listcolumn", joa.getJSONArray("listcolumn").toArray());
//			frontMap.put("list", listmap);
//			tableFrontendMap.put(tablename, frontMap);
//		});
//		//
//		preSetMap.put("frontend", tableFrontendMap);
		mpg.getCfg().setMap(preSetMap);
		//
		//
		mpg.getStrategy().setInclude(tableArray);
//		mpg.frontsideConfig = result;
		mpg.execute();
		return "ok";
	}

//	public static void main(String[] args) {
//		Set<String> of = Set.of("a", "aa", "aaa");
//		of.stream().reduce((a, b) -> {
//			return a + "," + b;
//		}).ifPresent(res -> {
//			System.out.println(res);
//		});
////		String[] array = (String[]) of.toArray();
////		StrategyConfig strategy = new StrategyConfig();
////		strategy.setInclude(array);
//		System.out.println(of.toArray(String[]::new));
//		String[] array2 = of.toArray((e) -> {
//			System.out.println(e);
//			return new String[e];
//		});
//		System.out.println(array2);
//		System.out.println("a");
//	}

//	public static void main(String[] args) {
//		CoreController c = new CoreController();
//		c.initEngine();
//		c.mpg.getStrategy().setInclude("user");
//		c.mpg.execute();
//	}

	private void initEngine() {
		// 全局配置
		GlobalConfig gc = new GlobalConfig();
//		String projectPath = "D:\\springworkspace\\olivier2";
//		String projectPath = "C:\\1\\demo";

		gc.setOutputDir(projectGeneratePath + "/src/main/java");
		gc.setAuthor(author);
		gc.setOpen(false);
		gc.setServiceName("%sService");
		mpg.setGlobalConfig(gc);
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setUrl(dburl);
//		dsc.setUrl(
//				"jdbc:mysql://localhost:3306/test?useUnicode=true&serverTimezone=GMT&useSSL=false&characterEncoding=utf8");
		dsc.setDriverName(driverName);
		dsc.setUsername(dbusername);
		dsc.setPassword(dbpassword);
		mpg.setDataSource(dsc);
		PackageConfig pc = new PackageConfig();
		pc.setModuleName(null);
		String packageParent = "com.leedarson." + projectname;
		pc.setParent(packageParent);
		mpg.setPackageInfo(pc);

		// 自定义配置，这里注入的配置会在gnerator类中注入到全局配置的根位置。
		InjectionConfig cfg = new InjectionConfig() {
			@Override
			public void initMap() {
				// to do nothing
				// 这里本来是官方示例中进行额外配置定制的部分。
				// 因为在这里代码中，这部分额外配置挪到了处理前端模块生成逻辑部分，因此这一块应该是没用了。
				// 仅仅作为当没有初始化后，自己一个赋予默认值的方式。
				Map<String, Object> map = new HashMap<String, Object>();
				int origin_map_size = this.getMap().size();
				if (origin_map_size < 1) {
					setMap(map);
				}
			}
		};
		// 这个干嘛的
		List<FileOutConfig> focList = new ArrayList<>();
		focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
			@Override
			public String outputFile(TableInfo tableInfo) {
				// 自定义输入文件名称
//				return projectPath + "/mybatis-plus-sample-generator/src/main/resources/mapper/" + pc.getModuleName()
//				+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
				return projectGeneratePath + "/src/main/resources/mapper/"
//						+ pc.getModuleName() + "/"
						+ tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
			}
		});
		cfg.setFileOutConfigList(focList);
		mpg.setCfg(cfg);
//        自定义模板
		TemplateConfig templateConfig = new TemplateConfig();
		templateConfig.setXml(null);
		templateConfig.setController("templates/controller.java");
		templateConfig.setEntity("templates/entity.java");
//		templateConfig.setMapper(null);
		templateConfig.setService("templates/service.java");
		templateConfig.setServiceImpl(null);
		mpg.setTemplate(templateConfig);
		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		strategy.setNaming(NamingStrategy.underline_to_camel);
		strategy.setColumnNaming(NamingStrategy.underline_to_camel);
//		strategy.setInclude(scanner("表名"));
		// 自定义继承的ServiceImpl类全称，带包名
		strategy.setSuperServiceClass("com.leedarson.service.Service");
//		strategy.setInclude("dept_cost", "role","user_post");// 这里可以是多个 , 填写不存在的表名不会生成文件。
//		strategy.setInclude("dept_cost");// 这里可以是多个 , 填写不存在的表名不会生成文件。
//		strategy.setSuperEntityColumns("id");//父类的字段，注释掉之后实体类将不存在该字段
//		strategy.setControllerMappingHyphenStyle(true);//驼峰标识转 - 字符
		strategy.setRestControllerStyle(true);// 更改为restful方案，controller会变更为restcontroller
		strategy.setTablePrefix(pc.getModuleName() + "_");
		mpg.setStrategy(strategy);
		mpg.setTemplateEngine(TEMPLATE_ENGINE);
	}
}
